package com.yc.commontlib.base

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
import kotlin.reflect.KFunction
import kotlin.reflect.KFunction2

/**
 * Creator: yc
 * Date: 2021/6/15 16:45
 * UseDes:
 */
open class YcBaseViewModel : ViewModel() {
    protected fun ViewModel.launch(block: suspend (coroutineScope: CoroutineScope) -> Unit): Job {
        return viewModelScope.launch {
            block(this)
        }
    }



    protected fun <T> Flow<T>.test2() {
        this.onStart {
            showLoading()
        }.onCompletion {
            hideLoading()
        }
    }

    fun use() {
        repository("asd", "asd").test2()
    }

    fun repository(data: String, data2: String) = flow {
        emit(data)
    }


    /**
     * 用于显示加载框
     */
    protected val _mIsShowLoading = MutableLiveData<Boolean>()
    val mIsShowLoading: LiveData<Boolean> = _mIsShowLoading
    protected var mLoadingJob: Job? = null
    protected var mDefaultDelayTime = 1500L
//    protected fun ViewModel.launchFlow(block: suspend () -> Unit) {
//        viewModelScope.launch {
//            block(
//                block
//        }.onStart {
//            showLoading()
//        }.onCompletion {
//            hideLoading()
//        })
//    }

    /**
     * 冷流开始时，显示加载框
     * 冷流结束时，自动隐藏加载框
     */
    protected fun <T> Flow<T>.hasLoading(delayTime: Long = mDefaultDelayTime): Flow<T> {
        onStart {
            showLoading(delayTime)
        }.onCompletion {
            hideLoading()
        }
        return this
    }

    /**
     * 冷流开始时，显示加载框
     * 冷流结束时，不会隐藏加载框，需手动调用hideLoading方法
     */
    protected fun <T> Flow<T>.hasLoadingNoAutoClose(delayTime: Long = mDefaultDelayTime): Flow<T> {
        onStart {
            showLoading(delayTime)
        }
        return this
    }

    /**
     * 显示加载框
     * @param delayTime Long  延迟delayTime毫秒后，再显示，减少请求很快返回时，导致闪下的体验。
     * 如果在delayTime毫秒内，请求就完成了，对话框就不会显示
     */
    protected fun showLoading(delayTime: Long = mDefaultDelayTime) {
        mLoadingJob?.cancel()
        mLoadingJob = viewModelScope.launch {
            delay(delayTime)
            _mIsShowLoading.postValue(true)
        }
    }

    /**
     * 隐藏加载框
     */
    protected fun hideLoading() {
        mLoadingJob?.cancel()
        _mIsShowLoading.postValue(false)
    }

    override fun onCleared() {
        hideLoading()
        super.onCleared()
    }
}